package org.jeecg.modules.job.api.controller;

import cn.hutool.core.util.RandomUtil;
import com.alibaba.fastjson.JSONObject;
import com.aliyuncs.exceptions.ClientException;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.constant.CacheConstant;
import org.jeecg.common.constant.CommonConstant;
import org.jeecg.common.system.api.ISysBaseAPI;
import org.jeecg.common.system.util.JwtUtil;
import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.common.util.*;
import org.jeecg.modules.base.service.BaseCommonService;
import org.jeecg.modules.job.api.model.SysLoginModel;
import org.jeecg.modules.job.api.util.WxUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

/**
 *
 */
@RestController
@RequestMapping("/api/login")
@Api(tags = "移动端用户登录")
@Slf4j
public class AppLoginController {
    @Autowired
    private ISysBaseAPI sysBaseApi;
    @Autowired
    private RedisUtil redisUtil;
    @Resource
    private BaseCommonService baseCommonService;

    /**
     * 退出登录
     *
     * @param request
     * @param response
     * @return
     */
    @ApiOperation("退出登录")
    @PostMapping(value = "/logout")
    public Result<Object> logout(HttpServletRequest request, HttpServletResponse response) {
        //用户退出逻辑
        String token = request.getHeader(CommonConstant.X_ACCESS_TOKEN);
        if (oConvertUtils.isEmpty(token)) {
            return Result.error("退出登录失败！");
        }
        String username = JwtUtil.getUsername(token);
        LoginUser sysUser = sysBaseApi.getUserByName(username);
        if (sysUser != null) {
            //update-begin--Author:wangshuai  Date:20200714  for：登出日志没有记录人员
            baseCommonService.addLog("用户名: " + sysUser.getRealname() + ",退出成功！", CommonConstant.LOG_TYPE_1, null, sysUser);
            //update-end--Author:wangshuai  Date:20200714  for：登出日志没有记录人员
            log.info(" 用户名:  " + sysUser.getRealname() + ",退出成功！ ");
            //清空用户登录Token缓存
            redisUtil.del(CommonConstant.PREFIX_USER_TOKEN + token);
            //清空用户登录Shiro权限缓存
            redisUtil.del(CommonConstant.PREFIX_USER_SHIRO_CACHE + sysUser.getId());
            //清空用户的缓存信息（包括部门信息），例如sys:cache:user::<username>
            redisUtil.del(String.format("%s::%s", CacheConstant.SYS_USERS_CACHE, sysUser.getUsername()));
            //调用shiro的logout
            SecurityUtils.getSubject().logout();
            return Result.ok("退出登录成功！");
        } else {
            return Result.error("Token无效!");
        }
    }

    /**
     * 短信验证码接口
     *
     * @param jsonObject
     * @return
     */
    @ApiOperation("短信验证码接口")
    @PostMapping(value = "/getSmsCode")
    public Result<String> getSmsCode(@RequestBody JSONObject jsonObject) {
        Result<String> result = new Result<String>();
        String mobile = jsonObject.get("phone").toString();
        //短信模板方式  0 .登录模板、1.注册模板、2.忘记密码模板
        String smsmode = jsonObject.get("smsmode").toString();
        log.info(mobile);
        if (oConvertUtils.isEmpty(mobile)) {
            result.setMessage("手机号不允许为空！");
            result.setSuccess(false);
            return result;
        }
        Object object = redisUtil.get(mobile);
        if (object != null) {
            result.setMessage("验证码10分钟内，仍然有效！");
            result.setSuccess(false);
            return result;
        }
        //随机数
        String captcha = RandomUtil.randomNumbers(6);
        JSONObject obj = new JSONObject();
        obj.put("code", captcha);
        try {
            boolean b = true;
            /**
             * smsmode 短信模板方式  0 .登录模板、1.注册模板、2.忘记密码模板
             */
            if (CommonConstant.SMS_TPL_TYPE_0.equals(smsmode)) {
                //登录模板
				b = DySmsHelper.sendSms(mobile, obj, DySmsEnum.LOGIN_TEMPLATE_CODE);
            } else if (CommonConstant.SMS_TPL_TYPE_1.equals(smsmode)) {
                //忘记密码模板
                b = DySmsHelper.sendSms(mobile, obj, DySmsEnum.REGISTER_TEMPLATE_CODE);
            } else if (CommonConstant.SMS_TPL_TYPE_2.equals(smsmode)) {
                //忘记密码模板
                b = DySmsHelper.sendSms(mobile, obj, DySmsEnum.FORGET_PASSWORD_TEMPLATE_CODE);
            }
            if (b == false) {
                result.setMessage("短信验证码发送失败,请稍后重试");
                result.setSuccess(false);
                return result;
            }
            //验证码10分钟内有效
            redisUtil.set(mobile, captcha, 600);
            //update-begin--Author:scott  Date:20190812 for：issues#391
            //result.setResult(captcha);
            //update-end--Author:scott  Date:20190812 for：issues#391
            result.setResult("发送成功");
            result.setMessage("发送成功");
            result.setSuccess(true);
        } catch (ClientException e) {
            e.printStackTrace();
            result.error500(" 短信接口未配置，请联系管理员！");
            return result;
        }
        return result;
    }

    /**
     * App账号密码登录
     *
     * @param sysLoginModel
     * @return
     * @throws Exception
     */
    @ApiOperation("app账号密码登录")
    @RequestMapping(value = "/mLogin", method = RequestMethod.POST)
    public Result<JSONObject> mLogin(@RequestBody SysLoginModel sysLoginModel) throws Exception {
        Result<JSONObject> result = new Result<JSONObject>();
        String username = sysLoginModel.getUsername();
        String password = sysLoginModel.getPassword();

        //1. 校验用户是否有效
        LoginUser sysUser = sysBaseApi.getUserByName(username);
        result = (Result<JSONObject>) sysBaseApi.checkUserIsEffective(sysUser);
        if (!result.isSuccess()) {
            return result;
        }
        //2. 校验用户名或密码是否正确
        String userpassword = PasswordUtil.encrypt(username, password, sysUser.getSalt());
        String syspassword = sysUser.getPassword();
        if (!syspassword.equals(userpassword)) {
            result.error500("用户名或密码错误");
            return result;
        }
        JSONObject obj = new JSONObject();
        //用户登录信息
        obj.put("userInfo", sysUser);

        // 生成token
        String token = JwtUtil.sign(username, syspassword);
        // 设置超时时间
        redisUtil.set(CommonConstant.PREFIX_USER_TOKEN + token, token);
        redisUtil.expire(CommonConstant.PREFIX_USER_TOKEN + token, JwtUtil.EXPIRE_TIME * 2 / 1000);

        //token 信息
        obj.put("token", token);
        result.setResult(obj);
        result.setSuccess(true);
        result.setCode(200);
        baseCommonService.addLog("用户名: " + username + ",登录成功[移动端]！", CommonConstant.LOG_TYPE_1, null);
        return result;
    }

    /**
     * App手机号登录接口
     *
     * @param jsonObject
     * @return
     */
    @ApiOperation("App手机号登录接口")
    @PostMapping("/mPhoneLogin")
    public Result<JSONObject> mPhoneLogin(@RequestBody JSONObject jsonObject) {
        Result<JSONObject> result = new Result<JSONObject>();
        String phone = jsonObject.getString("phone");
        String smscode = jsonObject.getString("code");
        Object code = redisUtil.get(phone);
//		if (!smscode.equals(code)) {
//			result.setMessage("手机验证码错误");
//			return result;
//		}
        //校验用户有效性
        LoginUser sysUser = sysBaseApi.getUserByName(phone);
        result = (Result<JSONObject>) sysBaseApi.checkUserIsEffective(sysUser);
        if (!result.isSuccess()) {
            if (!result.getMessage().equals("该用户不存在，请注册")) {
                return result;
            } else {
                //注册新用户
                sysUser = new LoginUser();
                sysUser.setPhone(phone);
                sysUser.setUsername(phone);
                sysUser.setRealname(phone);
                sysUser.setStatus(1);
                sysUser.setDelFlag(CommonConstant.DEL_FLAG_0);
                sysUser.setSex(0);
                sysUser.setUserIdentity(3);//移动端
                String s = UUID.randomUUID().toString().replace("-", "");
//				sysUser.setUuid(s);
                String salt = oConvertUtils.randomGen(8);
                sysUser.setSalt(salt);
                String password = "qkl123456";//默认密码
                String passwordEncode = PasswordUtil.encrypt(sysUser.getUsername(), password, salt);
                sysUser.setPassword(passwordEncode);
                sysUser.setUserCode(OrderUtils.getLocalTrmSeqNum());
                sysBaseApi.saveUser(sysUser);
            }
        }
        JSONObject obj = new JSONObject();
        //用户登录信息
        obj.put("userInfo", sysUser);
        // 生成token
        String token = JwtUtil.sign(sysUser.getUsername(), sysUser.getPassword());
        // 设置超时时间
        redisUtil.set(CommonConstant.PREFIX_USER_TOKEN + token, token);
        redisUtil.expire(CommonConstant.PREFIX_USER_TOKEN + token, JwtUtil.EXPIRE_TIME * 2 / 1000);

        //token 信息
        obj.put("token", token);
        result.setResult(obj);
        result.setSuccess(true);
        result.setCode(200);
        result.setMessage("登录成功");
        baseCommonService.addLog("用户名: " + phone + ",登录成功[移动端]！", CommonConstant.LOG_TYPE_1, null);
        return result;
    }


    /**
     * 小程序授权登录接口
     *
     * @param jsonObject
     * @return
     */
    @ApiOperation("小程序授权登录接口")
    @PostMapping("/mWxLogin")
    public Result<JSONObject> mWxLogin(@RequestBody JSONObject jsonObject) {
        Result<JSONObject> result = new Result<JSONObject>();
        try {
            String code = jsonObject.getString("code");
            String encryptedData = jsonObject.getString("encryptedData");
            String iv = jsonObject.getString("iv");
            Map<String, Object> map = new HashMap<>();
            String url = "https://api.weixin.qq.com/sns/jscode2session?appid=" + WxUtil.getAppId() + "&secret=" + WxUtil.getAppSecret() + "&js_code=" + code + "&grant_type=authorization_code";
            JSONObject json = WxUtil.doGetJson(url); //发起请求拿到key和openid
            System.out.println("返回过来的json数据:" + json.toString());
            String sessionkey = json.get("session_key").toString(); //会话秘钥
            String openid = json.get("openid").toString(); //用户唯一标识
            //根据openid判断用户是否存在
            LoginUser sysUser = sysBaseApi.getUserByThirdId(openid);
//            result = (Result<JSONObject>) sysBaseApi.checkUserIsEffective(sysUser);
            if (!oConvertUtils.isEmpty(encryptedData)) {
                String decrypts = WxUtil.decrypt(encryptedData, sessionkey, iv, "utf-8");//解密
                JSONObject jsons = JSONObject.parseObject(decrypts);
                if (sysUser == null) {
                    //注册新用户
                    sysUser = new LoginUser();
                    sysUser.setThirdId(openid);
                    sysUser.setAvatar(jsons.get("avatarUrl").toString());
                    sysUser.setUsername(openid);
                    sysUser.setNickname(jsons.get("nickName").toString());
                    sysUser.setSex((Integer) jsons.get("gender"));
                    sysUser.setStatus(1);
                    sysUser.setDelFlag(CommonConstant.DEL_FLAG_0);
                    sysUser.setUserIdentity(3);//移动端
                    String salt = oConvertUtils.randomGen(8);
                    sysUser.setSalt(salt);
                    String password = "qkl123456";//默认密码
                    String passwordEncode = PasswordUtil.encrypt(sysUser.getUsername(), password, salt);
                    sysUser.setPassword(passwordEncode);
                    //生成用户编码
                    sysUser.setUserCode(OrderUtils.getLocalTrmSeqNum());
                    sysBaseApi.saveUser(sysUser);
                } else {
                    //用户存在，更新头像等信息
//                    sysUser.setAvatar(jsons.get("avatarUrl").toString());
//                    sysUser.setNickname(jsons.get("nickName").toString());
//                    sysUser.setSex((Integer) jsons.get("gender"));
//                    sysBaseApi.updateUserInfo(sysUser);
                }
            }else{
                if (sysUser == null) {
                    return result.error500("用户不存在");
                }
            }
            JSONObject obj = new JSONObject();
            //用户登录信息
            obj.put("userInfo", sysUser);
            // 生成token
            String token = JwtUtil.sign(sysUser.getUsername(), sysUser.getPassword());
            // 设置超时时间
            redisUtil.set(CommonConstant.PREFIX_USER_TOKEN + token, token);
            redisUtil.expire(CommonConstant.PREFIX_USER_TOKEN + token, JwtUtil.EXPIRE_TIME * 2 / 1000);

            //token 信息
            obj.put("token", token);
            result.setResult(obj);
            result.setSuccess(true);
            result.setCode(200);
            result.setMessage("登录成功");
            baseCommonService.addLog("用户名: " + sysUser.getNickname() + ",登录成功[移动端]！", CommonConstant.LOG_TYPE_1, null);
        } catch (Exception e) {
            e.printStackTrace();
            System.err.println(e.getMessage());
        }
        return result;
    }
}